import { AppDataSource } from '../config/database';
import { SensorHourlyData } from '../entity/SensorHourlyData';
import {Between, LessThan} from 'typeorm';
import {sseManager} from "../sse/SseManager";

/**
 * 处理传感器数据采样：每小时一次，保留24小时内数据。
 * @param did 设备ID
 * @param data 传感器数据字段，如 { temperature: 25.5, humidity: 60 }
 * @param userId 用户ID
 */
export async function processSensorSnapshot(did: string, data: Record<string, any>, userId?: string): Promise<void> {
  const repo = AppDataSource.getRepository(SensorHourlyData);
  const now = new Date();

  // 对齐当前时间为小时起始（精度截断）
  const hourStart = new Date(now);
  hourStart.setMinutes(0, 0, 0);

  const toInsert: SensorHourlyData[] = [];

  for (const [metricType, value] of Object.entries(data)) {
    if (typeof value !== 'number') continue; // 只采样数值类型

    const sample = new SensorHourlyData();
    sample.deviceId = did;
    sample.metricType = metricType;
    sample.hourStart = hourStart;
    sample.metricValue = Number(value);

    toInsert.push(sample);
  }

  if (toInsert.length === 0) return;

  // 插入或更新（避免主键冲突）
  await repo.upsert(toInsert, ['deviceId', 'metricType', 'hourStart']);

  // 删除超过24小时的旧数据（保留当天当前小时前24小时）
  const expireTime = new Date(hourStart);
  expireTime.setHours(expireTime.getHours() - 24);

  await repo.delete({
    deviceId: did,
    hourStart: LessThan(expireTime)
  });

  console.log(`[SAMPLE] ${did} 采样完成，更新指标数：${toInsert.length}`);

  // 推送历史记录（按指标分别发送）
  if (userId) {
      for (const sample of toInsert) {
          const records = await repo.find({
              where: {
                  deviceId: did,
                  metricType: sample.metricType,
                  hourStart: Between(expireTime, now)
              },
              order: {hourStart: 'ASC'}
          });

          sseManager.sendTo(userId, {
              type: 'history',
              did,
              metric_type: sample.metricType,
              data: records.map(r => ({
                  hour: r.hourStart.toISOString(),
                  value: r.metricValue
              })),
              timestamp: new Date().toISOString()
          });
      }
  }
}
